package space.sakana.edusysback.service;

import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import space.sakana.edusysback.emu.QuestionEnum;
import space.sakana.edusysback.entity.Admin;
import space.sakana.edusysback.entity.question.Question;
import space.sakana.edusysback.entity.question.type.*;
import space.sakana.edusysback.mapper.AdminMapper;
import space.sakana.edusysback.mapper.question.QuestionMapper;
import space.sakana.edusysback.result.DataResult;
import space.sakana.edusysback.result.Result;
import space.sakana.edusysback.util.CookieUtil;

import java.util.LinkedList;
import java.util.List;

@Service
public class QuestionService {

    private QuestionMapper questionMapper;
    private AdminMapper adminMapper;

    @Autowired
    public void autowiredMapper(QuestionMapper questionMapper, AdminMapper adminMapper){
        this.questionMapper = questionMapper;
        this.adminMapper = adminMapper;
    }

    public Result getAllQuestion(HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(questionMapper.selectAllQuestion()));
    }

    public Result getSubjectQuestions(int sid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(questionMapper.selectQuestionBySid(sid)));
    }

    public Result getPaperQuestions(int pid, HttpServletRequest request, HttpServletResponse response) {
//        List<PaperItem> paperItems = paperItemMapper.selectPaperItemByPid(pid);
//        List<QuestionFull> questions = new LinkedList<>();
//        for (PaperItem item :paperItems) {
//            questions.add(new QuestionFull(questionMapper.selectQuestionById(item.getQid()), choiceMapper.selectChoicesByQid(item.getQid())));
//        }
//        return new DataResult(JSON.toJSONString(questions));
        return null;
    }

    public Result getQuestion(int qid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(questionMapper.selectQuestionById(qid)));
    }

    public Result getFullQuestion(int qid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        Question question = questionMapper.selectQuestionById(qid);
        QuestionBase questionBase = null;
        if (question.getType()== QuestionEnum.SINGLE_CHOICE.getQuestionInt()){
            questionBase = questionMapper.selectQuestionAById(question.getId());
        }
        else if (question.getType()==QuestionEnum.MULTIPLE_CHOICE.getQuestionInt()){
            questionBase = questionMapper.selectQuestionBById(question.getId());
        }
        else if (question.getType()==QuestionEnum.TRUE_FALSE_Q.getQuestionInt()){
            questionBase = questionMapper.selectQuestionCById(question.getId());
        }
        else if (question.getType()==QuestionEnum.ESSAY_QUESTION.getQuestionInt()){
            questionBase = questionMapper.selectQuestionDById(question.getId());
        }
        if (questionBase==null){
            return Result.failResult;
        }
        question.setQuestionBase(questionBase);
        return new DataResult(JSON.toJSONString(question));
    }

    @Transactional(rollbackFor=Exception.class)
    public Result updateQuestion(String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        Question question = JSON.parseObject(data, Question.class);
        questionMapper.updateQuestion(question);
        return Result.successResult;
    }

    @Transactional(rollbackFor=Exception.class)
    public Result addQuestionA(String data, int diff, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        SingleChoice singleChoice = JSON.parseObject(data, SingleChoice.class);
        Question question = new Question(singleChoice, diff);
        question.setType(singleChoice.getType());
        questionMapper.insertQuestion(question);
        singleChoice.setQid(question.getId());
        return new Result(questionMapper.insertQuestionA(singleChoice));
    }

    @Transactional(rollbackFor=Exception.class)
    public Result addQuestionB(String data, int diff, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        MultipleChoice multipleChoice = JSON.parseObject(data, MultipleChoice.class);
        if (multipleChoice.getAnswer().length()<2){
            return Result.failResult;
        }
        Question question = new Question(multipleChoice, diff);
        question.setType(multipleChoice.getType());
        questionMapper.insertQuestion(question);
        multipleChoice.setQid(question.getId());
        return new Result(questionMapper.insertQuestionB(multipleChoice));
    }

    public Result addQuestionC(String data, int diff, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        TrueFalseQ trueFalseQ = JSON.parseObject(data, TrueFalseQ.class);
        Question question = new Question(trueFalseQ, diff);
        question.setType(trueFalseQ.getType());
        questionMapper.insertQuestion(question);
        trueFalseQ.setQid(question.getId());
        return new Result(questionMapper.insertQuestionC(trueFalseQ));
    }

    public Result addQuestionD(String data, int diff, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        EssayQuestion essayQuestion = JSON.parseObject(data, EssayQuestion.class);
        Question question = new Question(essayQuestion, diff);
        question.setType(essayQuestion.getType());
        questionMapper.insertQuestion(question);
        essayQuestion.setQid(question.getId());
        return new Result(questionMapper.insertQuestionD(essayQuestion));
    }

    public Result updateBaseQuestion(int type, String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        QuestionBase questionBase = JSON.parseObject(data, QuestionEnum.getQuestionClass(type));
        int code__ = -1;
        if (type == QuestionEnum.SINGLE_CHOICE.getQuestionInt()){
            code__ = questionMapper.updateQuestionA((SingleChoice) questionBase);
        }else if (type == QuestionEnum.MULTIPLE_CHOICE.getQuestionInt()){
            code__ = questionMapper.updateQuestionB((MultipleChoice) questionBase);
        }else if (type == QuestionEnum.TRUE_FALSE_Q.getQuestionInt()){
            code__ = questionMapper.updateQuestionC((TrueFalseQ) questionBase);
        }else if (type == QuestionEnum.ESSAY_QUESTION.getQuestionInt()){
            code__ = questionMapper.updateQuestionD((EssayQuestion) questionBase);
        }
        Question question = questionMapper.selectQuestionById(questionBase.getQid());
        question.setTitle(questionBase.getTitle());
        question.setDiff(questionBase.getDiff());
        question.setSid(question.getSid());
        int code_ = questionMapper.updateQuestion(question);
        int code = 0;
        if (code_==1 && code__==1){
            code = 1;
        }
        return new Result(code);
    }

    public Result deleteQuestion(int qid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new Result(questionMapper.deleteQuestionById(qid));
    }
}
